home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Blender 2.49b / blender-2.49b-windows.exe / $_4_ / .blender / scripts / bpymodules / BPyRegistry.py < prev    next >
Text File  |  2009-08-31  |  8KB  |  268 lines

  1. # --------------------------------------------------------------------------
  2. # Module BPyRegistry version 0.1
  3. #   Helper functions to store / restore configuration data.
  4. # --------------------------------------------------------------------------
  5. # $Id: BPyRegistry.py 14353 2008-04-07 20:56:45Z theeth $
  6. #
  7. # ***** BEGIN GPL LICENSE BLOCK *****
  8. #
  9. # Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br
  10. #
  11. # This program is free software; you can redistribute it and/or
  12. # modify it under the terms of the GNU General Public License
  13. # as published by the Free Software Foundation; either version 2
  14. # of the License, or (at your option) any later version.
  15. #
  16. # This program is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
  19. # GNU General Public License for more details.
  20. #
  21. # You should have received a copy of the GNU General Public License
  22. # along with this program; if not, write to the Free Software Foundation,
  23. # --------------------------------------------------------------------------
  24.  
  25. # The Registry is a Python dictionary that is kept in Blender for as long as
  26. # the program is running, where scripts can store / restore persistent data
  27. # (data that is not lost when the script exits).  This module provides
  28. # functions to save and restore Registry entries as config data in the
  29. # bpydata/config folder.  Scripts just need to give an extra parameter to
  30. # the Blender.Registry.Get/Set() functions to have their data automatically
  31. # saved and restored when needed.
  32. #
  33. # Note: entries starting with an underscore are not saved, so script authors
  34. # can use that fact to define data that is not meant to be stored in a
  35. # config file.  Example: data to be passed to another script and references to
  36. # invalid data, like Blender objects and any function or method.
  37. #
  38. # Check the Blender.Registry documentation for more information.
  39.  
  40. import Blender
  41. from Blender import Registry, sys as bsys
  42.  
  43. _EXT = '.cfg' # file extension for saved config data
  44.  
  45. # limits:
  46. #MAX_ITEMS_NUM = 60 # max number of keys per dict and itens per list and tuple
  47. #MAX_STR_LEN = 300 # max string length (remember this is just for config data)
  48.  
  49. _CFG_DIR = ''
  50. if Blender.Get('udatadir'):
  51.     _CFG_DIR = Blender.sys.join(Blender.Get('udatadir'), 'config')
  52. if not _CFG_DIR or not bsys.exists(_CFG_DIR):
  53.     _CFG_DIR = Blender.sys.join(Blender.Get('datadir'), 'config')
  54. if not bsys.exists(_CFG_DIR):
  55.     _CFG_DIR = ''
  56.  
  57. # to compare against, so we don't write to a cvs tree:
  58. _CVS_SUBPATH = 'release/scripts/bpydata/config/'
  59. if bsys.dirsep == '\\':
  60.     _CVS_SUBPATH = _CVS_SUBPATH.replace('/', '\\')
  61.  
  62. _KEYS = [k for k in Registry.Keys() if k[0] != '_']
  63.  
  64. # _ITEMS_NUM = 0
  65.  
  66. def _sanitize(o):
  67.     "Check recursively that all objects are valid, set invalid ones to None"
  68.  
  69.     # global MAX_ITEMS_NUM, MAX_STR_LEN, _ITEMS_NUM
  70.  
  71.     valid_types = [int, float, bool, long, type]
  72.     valid_checked_types = [str, unicode]
  73.     # Only very simple types are considered valid for configuration data,
  74.     # functions, methods and Blender objects (use their names instead) aren't.
  75.  
  76.     t = type(o)
  77.  
  78.     if t == dict:
  79.         '''
  80.         _ITEMS_NUM += len(o)
  81.         if _ITEMS_NUM > MAX_ITEMS_NUM:
  82.             return None
  83.         '''
  84.         for k, v in o.iteritems():
  85.             o[k] = _sanitize(v)
  86.     elif t in [list, tuple]:
  87.         '''
  88.         _ITEMS_NUM += len(o)
  89.         if _ITEMS_NUM > MAX_ITEMS_NUM:
  90.             return None
  91.         '''
  92.         return [_sanitize(i) for i in o]
  93.     elif t in valid_types:
  94.         return o
  95.     elif t in valid_checked_types:
  96.         '''
  97.         if len(o) > MAX_STR_LEN:
  98.             o = o[:MAX_STR_LEN]
  99.         '''
  100.         return o
  101.     else: return None
  102.  
  103.     return o
  104.  
  105.  
  106. def _dict_to_str(name, d):
  107.     "Return a pretty-print version of the passed dictionary"
  108.     if not d: return 'None' # d can be None if there was no config to pass
  109.     
  110.     if name: l = ['%s = {' % name]
  111.     else: l = ['{']
  112.     #keys = d.keys()
  113.     for k,v in d.iteritems(): # .keys()
  114.         if type(v) == dict:
  115.             l.append("'%s': %s" % (k, _dict_to_str(None, v)))
  116.         else:
  117.             l.append("'%s': %s," % (k, repr(v)))
  118.     if name: l.append('}')
  119.     else: l.append('},')
  120.     return "\n".join(l)
  121.  
  122. _HELP_MSG = """
  123. Please create a valid scripts config dir tree either by
  124. copying release/scripts/ tree to your <blenderhome> dir
  125. or by copying release/scripts/bpydata/ tree to a user
  126. defined scripts dir that you can set in the 
  127. User Preferences -> Paths tab -> Python path input box.
  128. """
  129.  
  130. def _check_dir():
  131.     global _CFG_DIR, _CVS_SUBPATH, _HELP_MSG
  132.  
  133.     if not _CFG_DIR:
  134.         errmsg = "scripts config dir not found!\n%s" % _HELP_MSG
  135.         raise IOError, errmsg
  136.     elif _CFG_DIR.find(_CVS_SUBPATH) > 0:
  137.         errmsg = """
  138. Your scripts config dir:\n%s
  139. seems to reside in your local Blender's cvs tree.\n%s""" % (_CFG_DIR, _HELP_MSG)
  140.         raise SystemError, errmsg
  141.     else: return
  142.  
  143.  
  144. # API:
  145.  
  146. BPY_KEY_MISSING = 0
  147. BPY_KEY_IN_REGISTRY = 1
  148. BPY_KEY_IN_FILE = 2
  149.  
  150. def HasConfigData (key):
  151.     """
  152.     Check if the given key exists, either already loaded in the Registry dict or
  153.     as a file in the script data config dir.
  154.     @type key: string
  155.     @param key: a given key name.
  156.     @returns:
  157.         - 0: key does not exist;
  158.         - 1: key exists in the Registry dict only;
  159.         - 2: key exists as a file only;
  160.         - 3: key exists in the Registry dict and also as a file.
  161.     @note: for readability it's better to check against the constant bitmasks
  162.         BPY_KEY_MISSING = 0, BPY_KEY_IN_REGISTRY = 1 and BPY_KEY_IN_FILE = 2.
  163.     """
  164.  
  165.     fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT))
  166.  
  167.     result = BPY_KEY_MISSING
  168.     if key in Registry.Keys(): result |= BPY_KEY_IN_REGISTRY
  169.     if bsys.exists(fname): result |= BPY_KEY_IN_FILE
  170.  
  171.     return result
  172.  
  173.  
  174. def LoadConfigData (key = None):
  175.     """
  176.     Load config data from file(s) to the Registry dictionary.
  177.     @type key: string
  178.     @param key: a given key name.  If None (default), all available keys are
  179.         loaded.
  180.     @returns: None
  181.     """
  182.  
  183.     _check_dir()
  184.  
  185.     import os
  186.  
  187.     if not key:
  188.         files = \
  189.             [bsys.join(_CFG_DIR, f) for f in os.listdir(_CFG_DIR) if f.endswith(_EXT)]
  190.     else:
  191.         files = []
  192.         fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT))
  193.         if bsys.exists(fname): files.append(fname)
  194.  
  195.     for p in files:
  196.         try:
  197.             f = file(p, 'r')
  198.             lines = f.readlines()
  199.             f.close()
  200.             if lines: # Lines may be blank
  201.                 mainkey = lines[0].split('=')[0].strip()
  202.                 pysrc = "\n".join(lines)
  203.                 exec(pysrc)
  204.                 exec("Registry.SetKey('%s', %s)" % (str(mainkey), mainkey))
  205.         except Exception, e:
  206.             raise Warning(e) # Resend exception as warning
  207.  
  208.  
  209. def RemoveConfigData (key = None):
  210.     """
  211.     Remove this key's config file from the <(u)datadir>/config/ folder.
  212.     @type key: string
  213.     @param key: the name of the key to be removed.  If None (default) all
  214.         available config files are deleted.
  215.     """
  216.  
  217.     _check_dir()
  218.  
  219.     if not key:
  220.         files = \
  221.             [bsys.join(_CFG_DIR, f) for f in os.listdir(_CFG_DIR) if f.endswith(_EXT)]
  222.     else:
  223.         files = []
  224.         fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT))
  225.         if bsys.exists(fname): files.append(fname)
  226.  
  227.     import os
  228.  
  229.     try:
  230.         for p in files:
  231.             os.remove(p) # remove the file(s)
  232.     except Exception, e:
  233.         raise Warning(e) # Resend exception as warning
  234.  
  235.  
  236. def SaveConfigData (key = None):
  237.     """
  238.     Save Registry key(s) as file(s) in the <(u)datadir>/config/ folder.
  239.     @type key: string
  240.     @param key: the name of the key to be saved.  If None (default) all
  241.         available keys are saved.
  242.     """
  243.  
  244.     global _KEYS, _CFG_DIR
  245.  
  246.     _check_dir()
  247.  
  248.     if key: keys = [key]
  249.     else: keys = _KEYS
  250.  
  251.     for mainkey in keys:
  252.         cfgdict = Registry.GetKey(mainkey).copy()
  253.         for k in cfgdict: # .keys()
  254.             if not k or k[0] == '_':
  255.                 del cfgdict[k]
  256.  
  257.         if not cfgdict: continue
  258.  
  259.         try:
  260.             filename = bsys.join(_CFG_DIR, "%s%s" % (mainkey, _EXT))
  261.             f = file(filename, 'w')
  262.             output = _dict_to_str(mainkey, _sanitize(cfgdict))
  263.             if output!='None':
  264.                 f.write(output)
  265.                 f.close()
  266.         except Exception, e:
  267.             raise Warning(e) # Resend exception as warning
  268.